C++实现LRU算法
描述
原题:146. LRU 缓存 - 力扣(LeetCode)
请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache 类:
LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 
int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。 
void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。 
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。
示例
输入
[“LRUCache”, “put”, “put”, “get”, “put”, “get”, “put”, “get”, “get”, “get”]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
输出
[null, null, null, 1, null, -1, null, -1, 3, 4]
解释
1 2 3 4 5 6 7 8 9 10
   | LRUCache lRUCache = new LRUCache(2); lRUCache.put(1, 1);  lRUCache.put(2, 2);  lRUCache.get(1);     lRUCache.put(3, 3);  lRUCache.get(2);     lRUCache.put(4, 4);  lRUCache.get(1);     lRUCache.get(3);     lRUCache.get(4);    
   | 
 
提示
1 <= capacity <= 3000 
0 <= key <= 10000 
0 <= value <= 105 
- 最多调用 
2 * 105 次 get 和 put 
核心代码
本题的思想在于要在O(1)时间复杂度上完成 get 和 put 操作。对于 get 则使用哈希表(C++的 std::unordered_map),对于 put 则使用双链表,同时采用伪头尾指针记录,即可在O(1)时间内完成操作。理解结构图很重要,数据结构图如下:

哈希表
1
   | std::unordered_map<int, LinkListNode*> _hashmap; 
   | 
 
双链表
1 2 3 4 5 6 7 8 9
   |  typedef struct LinkListNode {     int key, value;     LinkListNode* prev;     LinkListNode* next;     LinkListNode():key(0),value(0),prev(nullptr),next(nullptr){};     LinkListNode(int key, int value):key(key),value(value),prev(nullptr),next(nullptr){} }LinkListNode;
 
 
  | 
 
初始化
1 2 3 4 5 6 7
   |      LRUCache(int capacity):_capacity(capacity), _size(0) {         _dummyHead = new LinkListNode();         _dummyTail = new LinkListNode();         _dummyHead->next = _dummyTail;         _dummyTail->prev = _dummyHead;     }
 
  | 
 
⭐获取cache
1 2 3 4 5 6 7 8 9 10
   |      int get(int key) {         if(!_hashmap.count(key)) {              return -1;         }                  LinkListNode* node = _hashmap[key];         moveToHead(node);         return node->value;     }
 
  | 
 
⭐加入cahce
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
   |     void put(int key, int value) {        if(!_hashmap.count(key)) {             LinkListNode* node = new LinkListNode(key, value);                        if(_size >= _capacity){                                   _hashmap.erase(_dummyTail->prev->key);                                  removeNode(_dummyTail->prev);              } else {                                _size++;            }                        _hashmap[key] = node;                        addToHead(node);        } else {                        LinkListNode* node = _hashmap[key];            node->value = value;                        moveToHead(node);    	}    }
 
  | 
 
剩下的 删除指定节点 、移动指定节点到头节点、增加节点到头节点 实现如下
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
   |  typedef struct LinkListNode {     int key, value;     LinkListNode* prev;     LinkListNode* next;     LinkListNode():key(0),value(0),prev(nullptr),next(nullptr){};     LinkListNode(int key, int value):key(key),value(value),prev(nullptr),next(nullptr){} }LinkListNode;
  class LRUCache { private:          int _capacity;          int _size;      std::unordered_map<int, LinkListNode*> _hashmap;      LinkListNode* _dummyHead;     LinkListNode* _dummyTail; public:          LRUCache(int capacity):_capacity(capacity), _size(0) {         _dummyHead = new LinkListNode();         _dummyTail = new LinkListNode();         _dummyHead->next = _dummyTail;         _dummyTail->prev = _dummyHead;     }          int get(int key) {         if(!_hashmap.count(key)) {              return -1;         }                  LinkListNode* node = _hashmap[key];         moveToHead(node);         return node->value;     }          void put(int key, int value) {         if(!_hashmap.count(key)) {              LinkListNode* node = new LinkListNode(key, value);                          if(_size >= _capacity){                                     _hashmap.erase(_dummyTail->prev->key);                                    removeNode(_dummyTail->prev);               } else {                                  _size++;             }                          _hashmap[key] = node;                          addToHead(node);         } else {                          LinkListNode* node = _hashmap[key];             node->value = value;                          moveToHead(node);     }     }          void removeNode(LinkListNode* node) {         if(node == nullptr) return;         node->prev->next = node->next;         node->next->prev = node->prev;         delete node;     }          void moveToHead(LinkListNode* node) {         if(node == nullptr) return;         node->next->prev = node->prev;         node->prev->next = node->next;
          node->next = _dummyHead->next;         node->prev = _dummyHead;         _dummyHead->next->prev = node;         _dummyHead->next = node;     }          void addToHead(LinkListNode* node) {         if(node == nullptr) return;
          node->next = _dummyHead->next;         node->prev = _dummyHead;         _dummyHead->next->prev = node;         _dummyHead->next = node;     } };
 
 
  | 
 
运行结果
